#include "app_message.h"
#include "log/log.h"
#include "cJSON/cJSON.h"
#include <stdlib.h>
#include <string.h>
// 得到一个十六进制字符对应的字符的十进制的ASCII值
//'0'-'9'->0-9
//'A'-'F'->10-15
//'a'-'f'->10-15
static int hex_to_char(char hex)
{
    if (hex >= '0' && hex <= '9')
    {
        return hex - '0';
    }
    else if (hex >= 'a' && hex <= 'f')
    {
        return hex - 'a' + 10;
    }
    else if (hex >= 'A' && hex <= 'F')
    {
        return hex - 'A' + 10;
    }
}
// 将16进制字符串转换为对应的字符串
//"61626364"->"abcd"
static char *hex_to_str(char *hex_str, int *str_len)
{
    // 十六进制字符串的长度
    int hex_len = strlen(hex_str);
    if (hex_len % 2 != 0)
    {
        log_error("hex_str len error");
        return NULL;
    }
    // 得到对应的字符串长度，并保存到str_len
    *str_len = hex_len / 2;
    // 分配存储对应字符串的空间
    char *str = (char *)malloc(*str_len + 1);
    // 遍历hex_str,将每两位十六进制的字符转换为对应的字符串
    for (int i = 0; i < hex_len - 1; i += 2)
    {
        // int high_val = hex_to_char(hex_str[i]);    // a=>10<<4
        // int low_val = hex_to_char(hex_str[i + 1]); // b=>11
        // str[i / 2] = (high_val << 4) | low_val;
        sscanf(&hex_str[i], "%02x", (unsigned int *)&str[i / 2]);
    }
    // 在str中添加结束符'\0'
    str[*str_len] = '\0';
    return str;
}
// 将字符串转换为16进制字符串
static char *str_to_hex(char *str, int str_len)
{
    // 分配要生成的16进制字符串的空间
    char *hex_str = (char *)malloc(str_len * 2 + 1);
    // 遍历str,将每个字符的十六进制字符添加到hex_str中
    for (int i = 0; i < str_len; i++)
    {
        sprintf(hex_str + i * 2, "%02x", str[i]);
    }
    // 向hex_str中添加结束符'\0'
    hex_str[str_len * 2] = '\0';
    return hex_str;
}
Message *app_message_initByBinary(char *binary, int len)
{
    Message *message = (Message *)malloc(sizeof(Message));
    memset(message, 0, sizeof(Message));
    // 二进制数据格式
    // byte1 conn_type;
    // byte2 id_len;
    // byte4 msg_len;
    // byte4 (id_len+msg_len) msg+id;
    //  拷贝conn_type
    memcpy(&message->conn_Type, binary, 1);
    // 拷贝id_len
    memcpy(&message->id_len, binary + 1, 1);
    // 拷贝msg_len
    memcpy(&message->msg_len, binary + 2, 1);
    // 检查len
    if (len != 3 + message->id_len + message->msg_len)
    {
        log_error("binary len error");
        free(message);
        return NULL;
    }
    // 拷贝payload
    message->payload = (char *)malloc(message->id_len + message->msg_len);
    memcpy(message->payload, binary + 3, message->id_len + message->msg_len);
    return message;
}
Message *app_message_initByJson(char *json)
{
    // 初始化message空间
    Message *message = (Message *)malloc(sizeof(Message));
    memset(message, 0, sizeof(Message));
    // 解析json得到conn_type id_hex msg_hex
    cJSON *root = cJSON_Parse(json);
    if (root == NULL)
    {
        log_error("json parse error");
        free(message);
        return NULL;
    }
    cJSON *type_Obj = cJSON_GetObjectItem(root, "conn_type");
    cJSON *id_Obj = cJSON_GetObjectItem(root, "id");
    cJSON *msg_Obj = cJSON_GetObjectItem(root, "msg");
    if (type_Obj == NULL || id_Obj == NULL || msg_Obj == NULL)
    {
        log_error("json中没有conn_type或id或msg");
        free(message);
        return NULL;
    }
    int conn_type = type_Obj->valueint;
    char *id_hex = id_Obj->valuestring;
    char *msg_hex = msg_Obj->valuestring;
    // 将conn_type给message->conn_type
    message->conn_Type = conn_type;
    // 将id_hex msg_hex 转换为id和msg
    // 将id的长度给message->id_len
    // 将msg的长度给message->msg_len
    char *id = hex_to_str(id_hex, &message->id_len);
    char *msg = hex_to_str(msg_hex, &message->msg_len);
    // 将id和msg给message->payload
    message->payload = (char *)malloc(message->id_len + message->msg_len);
    memcpy(message->payload, id, message->id_len);
    memcpy(message->payload + message->id_len, msg, message->msg_len);
    // 释放json对象
    cJSON_Delete(root);
    // 释放id和msg
    free(id);
    free(msg);
    log_debug("message->conn_Type:%d,id_len:%d,msg_len:%d,payload:%s", message->conn_Type, message->id_len, message->msg_len, message->payload);
    return message;
}
int app_message_toBinary(Message *message, char *binary, int len)
{
    // 二进制数据格式
    // byte1 conn_type;
    // byte2 id_len;
    // byte4 msg_len;
    // byte4 (id_len+msg_len) msg+id;
    // 检查len
    if (len < 3 + message->id_len + message->msg_len)
    {
        log_error("binary len error");
        return -1;
    }
    // 拷贝conn_type
    memcpy(binary, &message->conn_Type, 1); // 拷贝的是conn_type的低位字节
    // 拷贝id_len
    memcpy(binary + 1, &message->id_len, 1);
    // 拷贝msg_len
    memcpy(binary + 2, &message->msg_len, 1);
    // 拷贝payload
    memcpy(binary + 3, message->payload, message->id_len + message->msg_len);
    return 3 + message->id_len + message->msg_len;
}

int app_message_toJson(Message *message, char *json, int len)
{
    // 创建空cJSON对象
    cJSON *root = cJSON_CreateObject();
    // 将message的conn_type添加到json对象
    cJSON_AddNumberToObject(root, "conn_type", message->conn_Type);
    // 从message的payload中提取id和msg
    // char *id = malloc(message->id_len);
    // memcpy(id, message->payload, message->id_len);
    // char *msg = malloc(message->msg_len);
    // memcpy(msg, message->payload + message->id_len, message->msg_len);
    // 将message中的payload转换为16进制字符串，并添加到json对象
    char *id_hex = str_to_hex(message->payload, message->id_len);
    cJSON_AddStringToObject(root, "id", id_hex);
    char *msg_hex = str_to_hex(message->payload + message->id_len, message->msg_len);
    cJSON_AddStringToObject(root, "msg", msg_hex);
    // 将json对象转换为字符串
    char *json_str = cJSON_PrintUnformatted(root);
    if (len < strlen(json_str) + 1)
    {
        log_error("json len error");
        return -1;
    }
    // 将json字符串拷贝到json参数中
    strcpy(json, json_str);
    // 释放json字符串
    cJSON_Delete(root);
    free(json_str);
    // 释放id_hex和msg_hex
    free(id_hex);
    free(msg_hex);
    // 返回json字符串的长度
    return strlen(json);
}

void app_message_free(Message *message)
{
    if (message->payload)
    {
        free(message->payload);
    }
    free(message);
}